package com.iot.ammeter.service.impl.web.other;

import com.iot.ammeter.constant.Constant;
import com.iot.ammeter.dto.web.email.CheckEmail;
import com.iot.ammeter.service.other.SendEmailService;
import com.iot.ammeter.utils.CheckTool;
import com.iot.ammeter.utils.RedisUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.time.DateFormatUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.mail.javamail.JavaMailSender;
import org.springframework.mail.javamail.MimeMessageHelper;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;

import javax.mail.internet.MimeMessage;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.text.MessageFormat;
import java.util.Date;
import java.util.Random;

/**
 * @ClassName: SendEmailServiceImpl
 * @Author: Basil
 * @Date: 2021/9/26 下午3:03
 * @Version: 1.0
 * @Description: 发送邮件实现类
 **/
@Service
@Slf4j
public class SendEmailServiceImpl implements SendEmailService {

    @Value("${spring.mail.username}")
    private String sender;
    private final JavaMailSender javaMailSender;
    private final Random random;
    private final RedisUtil redisUtil;

    public SendEmailServiceImpl(JavaMailSender javaMailSender, Random random, RedisUtil redisUtil) {
        this.javaMailSender = javaMailSender;
        this.random = random;
        this.redisUtil = redisUtil;
    }

    /**
     * 发送邮箱邮件
     *
     * @param email 邮箱号
     * @param type  类型
     *              1：注册验证码邮件
     *              2：重置密码验证码邮件
     * @return 发送邮件验证码成功或者失败
     */
    @Async
    @Override
    public String sendEmailCaptcha(String email, String type) {
        //校验邮箱
        if (!CheckTool.isEmail(email.trim())) {
            return Constant.SendEmailTips.INCORRECT_EMAIL_FORMAT;
        }

        // 构建一个邮件对象
        MimeMessage message = javaMailSender.createMimeMessage();
        try {
            String title = "";
            String tip = "";
            MimeMessageHelper helper = new MimeMessageHelper(message, true, "UTF-8");
            // 设置邮件发送者，这个跟application.yml中设置的要一致
            helper.setFrom(sender);
            // 发送给 email
            helper.setTo(email.trim());
            helper.setSentDate(new Date());
            //随机生成功 6位 验证码
            int temp = random.nextInt(999999);
            String code = String.valueOf(temp > 100000 ? temp : temp + 100000);
            log.info("sendEmail ===>{} -- code-> {} ", email, code);
            if (Constant.Email.REGISTERED.equals(type.trim())) {
                title = "注册验证码";
                tip = "注册验证码";
                // 将验证码存入redis中，并设置过期时间
                redisUtil.set(Constant.Redis.REGISTERED_WEB_USER + email.trim(), code, 60 * 10);
            } else if (Constant.Email.RESET.equals(type.trim())) {
                title = "重置密码验证码";
                tip = "重置密码验证码";
                // 将验证码存入redis中，并设置过期时间
                redisUtil.set(Constant.Redis.RESET_PASSWORD + email.trim(), code, 60 * 10);
            } else if (Constant.Email.UPDATE.equals(type.trim())) {
                title = "更换邮箱验证码";
                tip = "更换邮箱验证码";
                // 将验证码存入redis中，并设置过期时间
                redisUtil.set(Constant.Redis.UPDATE_EMAIL + email.trim(), code, 60 * 10);
            } else {
                return Constant.SendEmailTips.THE_SENT_EMAIL_TYPE_IS_INCORRECT;
            }
            // 设置邮件主题
            helper.setSubject(title);
            // 设置邮件的正文
            helper.setText(buildContent(code, tip), true);
            // 发送邮件
            javaMailSender.send(message);
        } catch (Exception e) {
            e.printStackTrace();
            return Constant.SendEmailTips.SEND_CAPTCHA_ERROR;
        }

        return Constant.SendEmailTips.SEND_CAPTCHA_SUCCESS + email;
    }

    /**
     * 发送邮箱邮件
     *
     * @param email 邮箱号
     * @param type  类型
     *              1：注册验证码邮件
     *              2：重置密码验证码邮件
     * @return 发送邮件验证码成功或者失败
     */
    @Async
    @Override
    public String appSendEmailCaptcha(String email, String type) {
        //校验邮箱
        if (!CheckTool.isEmail(email.trim())) {
            return Constant.SendEmailTips.INCORRECT_EMAIL_FORMAT;
        }

        // 构建一个邮件对象
        MimeMessage message = javaMailSender.createMimeMessage();
        try {
            String title = "";
            String tip = "";
            MimeMessageHelper helper = new MimeMessageHelper(message, true, "UTF-8");
            // 设置邮件发送者，这个跟application.yml中设置的要一致
            helper.setFrom(sender);
            // 发送给 email
            helper.setTo(email.trim());
            helper.setSentDate(new Date());
            //随机生成功 6位 验证码
            int temp = random.nextInt(999999);
            String code = String.valueOf(temp > 100000 ? temp : temp + 100000);
            log.info("sendEmail ===>{} -- code-> {} ", email, code);
            if (Constant.Email.REGISTERED.equals(type.trim())) {
                title = "注册验证码";
                tip = "注册验证码";
                // 将验证码存入redis中，并设置过期时间
                redisUtil.set(Constant.Redis.REGISTERED_APP_USER + email.trim(), code, 60 * 10);
            } else if (Constant.Email.RESET.equals(type.trim())) {
                title = "重置密码验证码";
                tip = "重置密码验证码";
                // 将验证码存入redis中，并设置过期时间
                redisUtil.set(Constant.Redis.RESET_PASSWORD + email.trim(), code, 60 * 10);
            } else {
                return Constant.SendEmailTips.THE_SENT_EMAIL_TYPE_IS_INCORRECT;
            }
            // 设置邮件主题
            helper.setSubject(title);
            // 设置邮件的正文
            helper.setText(buildContent(code, tip), true);
            // 发送邮件
            javaMailSender.send(message);
        } catch (Exception e) {
            e.printStackTrace();
            return Constant.SendEmailTips.SEND_CAPTCHA_ERROR;
        }
        return Constant.SendEmailTips.SEND_CAPTCHA_SUCCESS + email;
    }

    @Override
    public boolean verifyCaptcha(CheckEmail checkEmail) {
        String captcha = checkEmail.getCaptcha().trim();
        //判断类型
        if (Constant.Email.REGISTERED.equals(checkEmail.getType())) {
            String registerCaptchaByWebUser = (String) redisUtil.get(Constant.Redis.REGISTERED_WEB_USER + checkEmail.getEmail().trim());
            return registerCaptchaByWebUser != null && registerCaptchaByWebUser.equals(captcha);
        } else if (Constant.Email.RESET.equals(checkEmail.getType())) {
            String resetCaptchaByWebUser = (String) redisUtil.get(Constant.Redis.RESET_PASSWORD + checkEmail.getEmail().trim());
            return resetCaptchaByWebUser != null && resetCaptchaByWebUser.equals(captcha);
        } else if (Constant.Email.UPDATE.equals(checkEmail.getType())) {
            String updateByWebUser = (String) redisUtil.get(Constant.Redis.UPDATE_EMAIL + checkEmail.getEmail().trim());
            return updateByWebUser != null && updateByWebUser.equals(captcha);
        }
        return false;
    }

    /**
     * html 邮件内容
     *
     * @param code 验证码
     * @param tip  提示  ： 注册，重置
     * @return
     * @throws IOException
     */
    private String buildContent(String code, String tip) throws IOException {

        //加载邮件html模板
        String fileName = "static/email-model.html";
        InputStream inputStream = ClassLoader.getSystemResourceAsStream(fileName);
        BufferedReader fileReader = new BufferedReader(new InputStreamReader(inputStream));
        StringBuffer buffer = new StringBuffer();
        String line = "";
        try {
            while ((line = fileReader.readLine()) != null) {
                buffer.append(line);
            }
        } catch (Exception e) {
            log.error("读取文件失败，fileName:{}", fileName, e);
        } finally {
            inputStream.close();
            fileReader.close();
        }

        String contentText = "验证码为：<span style='color: red '>" + code + "</span> ，有效时长为：10分钟。<br>The verification code is:" + code + ", and the valid time is: 10 minutes. ";


        //绿色
        String emailHeadColor = "#10fa81";
        String date = DateFormatUtils.format(new Date(), "yyyy/MM/dd HH:mm:ss");
        //填充html模板中的五个参数
        String htmlText = MessageFormat.format(buffer.toString(), emailHeadColor, tip, contentText, date);
        return htmlText;
    }

}
